<?php
/**

 *  This class allows to fetches content from one provided URL and feeds that content into the callback function. 
 *  
 *  To create an GadgetRequest we need to call the constructor like this:
 *  <code>
 *  $gadget_request = new GadgetRequest('gadgetRequest','http://graargh.returnstrue.com/buh/fetchme.php');
 *  </code>
 *  Doing this we create an GadgetRequest Object identified by 'gadgetRequest' and that it will be made to the 'http://graargh.returnstrue.com/buh/fetchme.php' url. After creating the object we need to set it's content type like this:
 *  <code>
 *  $gadget_request->setMethod(GadgetMethodType::POST);
 *  </code>
 *  Here we are saying that the request will be as POST to the provided URL.
 *  Next we need to define what will be submited to the container and here we use something like this:
 *  <code>$gadget_request->setPostData(GadgetsIO::encodeValues('{ data1 : "test", data2 : 1234566 }',true));
 *  </code>
 *  Now to actually perform the Request we need to call the GadgetsIO class like this:
 *  <code>
 *  $this->gadget_response = GadgetsIO::makeRequest($gadget_request);
 *  echo JSFunction::addJSTags(GadgetsUtil::registerOnLoadHandler($gadget_request->->getJSRequestFunction()));
 *  </code>
 *  That it will return an GadgetResponse object that will be used in the view and the last line will say to the container to execute the this request when the gadget is loaded.
 *    
 *  In the view we can use this code:
 *  <code>
 *  //view
 *  <div id="post">post</div>
 *  
 *  <?php echo JSFunction::addJSOpenTag($gadget_response->getJSFunction()); ?>
 *    var text = <?php echo $gadget_response->getText(); ?>
 *    document.getElementById('post').innerHTML = text;
 *    <?php echo GadgetsWindow::adjustHeight(); ?>
 *  <?php echo JSFunction::addJSCloseTag($gadget_response->getJSFunction()) ?>
 *  </code>
 *  This code will handle the response and set the div "post" with the content received by the container.
 * @package    gadgets
 * @author     Daniel Botelho <botelho.daniel@gmail.com>
 */
class GadgetRequest
{
  private static $PARAMS_PATTERN = "%s[%s] = %s;\n";
	
  private $url;
  /**
   * The URL's variable name
   *
   * @var string
   */
  protected $url_var;
  
  //nome da variável usada para fazer o request
  /**
   * The id used to create variable and generate javascript content
   *
   * @var string
   */
  protected $id;

  //função JavaScript que vai fazer o request
  private /*JSFunction*/ $request_func;

  //função JavaScript que vai receber o response
  private /*JSFunction*/ $response_func;
  
  //nome da variável usada para fazer o POST_DATA
  private $postData_var;
  //o conteúdo do POST_DATA
  private $postData;

  // nome da variável que guarda a lista dos parametros
  /**
   * The params variable name
   *
   * @var string
   */
  protected $params_var;
  
  // Lista de Pedidos que vão ser feitos ao container
  /**
   * Prameters used to make the request
   *
   * @var array This of params
   */
  protected $params; 
  
  /**
   * This constructor creates an GadgetRequest object with the $id and the $url
   *
   * @param string $id
   * @param string $url
   * @throws GadgetRequest must have an ID and an URL!
   */
  function __construct($id,$url)
  {
  	if($id==null || $url==null)
  	  throw new Exception("GadgetRequest must have an ID and an URL!");
    $this->id = $id;
    $this->params_var = $id."_params";
    $this->params = array();
    $this->url = $url;
    $this->url_var = $id."_url";
    $this->postData_var = $id.'_postData';
    $this->request_func = new JSFunction($id.'_request',null,null);
    $this->response_func = new JSFunction($id.'_response','data',null);
  }
  
  /**
   * Get's the request Javascript function
   *
   * @return JSFunction
   */
  public function getJSRequestFunction() { return $this->request_func; }
  
  /**
   * Get's the response Javascript function
   *
   * @return JSFunction
   */
  public function getJSResponseFunction() { return $this->response_func; }
  
  /**
   * Set's the response Javascript function
   *
   * @return JSFunction
   */
  public function setJSResponseFunction(JSFunction $response_func) { $this->response_func = $response_func; }
    
  /**
   * This method generates this "html" reques
   *
   * @return string The HTML coded generated by this request
   */
  public function generateRequest()
  {

    $html = 'var '.$this->params_var." = {};\n";
    $html .= 'var '.$this->url_var." = '".$this->getURL()."';\n";
    
    if($this->getPostData())
      $html .= 'var '.$this->getPostDataVar()." = ".$this->getPostData().";\n";

    foreach($this->params as $key => $value) {
      $html .= sprintf(GadgetRequest::$PARAMS_PATTERN,$this->params_var,$key,$value);
    }
    return $html;
  }
  
  /**
   * The method returns the variable name that has the post data content
   *
   * @return string The variable name
   */
  public function getPostDataVar()
  {
  	return $this->postData_var;
  }
  
  /**
   * Set's the authorization type of this request
   *
   * @param string $type One of the constant GadgetAuthorizationType values 
   * @see GadgetAuthorizationType
   */
  public function setAuthorization($type)
  {
  	$this->params[GadgetRequestParameters::AUTHORIZATION] = $type;
  }
  
  /**
   * Get's the authorization type of this request
   *
   * @return string One of the constant GadgetAuthorizationType values 
   * @see GadgetAuthorizationType
   */
  public function getAuthorization()
  {
  	return $this->params[GadgetRequestParameters::AUTHORIZATION];
  }
  
  /**
   * Get's the content type of this request
   * 
   * @return string One of the constant GadgetContentType values 
   * @see GadgetContentType
   */
  public function getContentType()
  {
  	return $this->params[GadgetRequestParameters::CONTENT_TYPE];
  }
  
  /**
   * Set's the content type of this request
   *
   * @param string $type One of the constant GadgetContentType values 
   * @see GadgetContentType
   */
  public function setContentType($type)
  {
  	$this->params[GadgetRequestParameters::CONTENT_TYPE] = $type;
  }
  
  /**
   * If the content is a feed, whether to fetch summaries for that feed; defaults to false.
   *
   * @param boolean $bool 
   */
  public function setGetSummaries($bool)
  {
  	$this->params[GadgetRequestParameters::GET_SUMMARIES] = $bool;
  }
  
  /**
   * Get's the value of the GET_SUMMARIES object
   *
   * @return boolean
   */
  public function getGetSummaries()
  {
  	return $this->params[GadgetRequestParameters::GET_SUMMARIES];
  }
  /**
   * The HTTP headers to send to the URL; defaults to null. Specified as a Map.<String,String>.
   *
   * @param string $headers
   */
  public function setHeaders($headers)
  {
  	$this->params[GadgetRequestParameters::HEADERS] = $headers;
  }

  /**
   * Get's the HEADERS value
   *
   * @return string
   */
  public function getHeaders()
  {
  	return $this->params[GadgetRequestParameters::HEADERS];
  }
  /**
   * The method to use when fetching content from the URL; defaults to GadgetMethodType::GET
   *
   * @param string $type One of the constant GadgetMethodType values 
   * @see GadgetMethodType
   */
  public function setMethod($type)
  {
  	$this->params[GadgetRequestParameters::METHOD] = $type;
  }
  /**
   * Get's the Method type of this request
   * 
   * @return string One of the constant GadgetMethodType values 
   * @see GadgetMethodType
   */
  public function getMethod()
  {
  	return $this->params[GadgetRequestParameters::METHOD];
  }
  /**
   * If the content is a feed, the number of entries to fetch; defaults to 3. Specified as a Number.
   *
   * @param int $numEntries
   */
  public function setNumEntries($numEntries)
  {
  	$this->params[GadgetRequestParameters::NUM_ENTRIES] = $numEntries;
  }
  
  /**
   * Get's the number of entries to fetch
   *
   * @return int
   */
  public function getNumEntries()
  {
  	return $this->params[GadgetRequestParameters::NUM_ENTRIES];
  }
  /**
   * The data to send to the URL using the POST method; defaults to null. Specified as a String.
   *
   * @param string $postData
   */
  public function setPostData($postData)
  {
  	$this->postData = $postData;
  	$this->params[GadgetRequestParameters::POST_DATA] = $this->postData_var;
  }
  
  /**
   * Get's the data that will be posted
   *
   * @return string
   */
  public function getPostData()
  {
  	return $this->postData;
  }
  
  /**
   * Get's the URL where the content is located
   *
   * @return string The URL where the content is located
   */
  public function getURL()
  {
  	return $this->url;
  }
  /**
   * Set's the URL where the content is located
   *
   * @param string $url The URL where the content is located
   */
  public function setURL($url)
  {
  	$this->url = $url;
  }
  
  /**
   * Get's the URL's variable name 
   *
   * @return string URL varible name
   */
  public function getURLVarName()
  {
  	return $this->url_var;
  }
  
  /**
   * Set's the URL's variable name 
   *
   * @param string URL varible name
   */
  public function setURLVarName($url_var)
  {
  	$this->url_var = $url_var;
  }
  
  /**
   * Get's the reques params variable name 
   *
   * @return string Params variable name
   */ 
  public function getParamsVarName()
  {
  	return $this->params_var;
  }
    
  /**
   * Set's the params variable name 
   *
   * @param string Params varible name
   */ 
  public function setParamsVarName($params_var)
  {
  	$this->params_var = $params_var;
  }
  
  
  protected function resetParams(){
  	$this->params= array();
  }
}